package com.bringspring.visualdev.generater.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.config.ConfigValueUtil;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.database.model.entity.DbLinkEntity;
import com.bringspring.common.database.model.DataSourceModel;
import com.bringspring.common.model.visiual.DownloadCodeForm;
import com.bringspring.common.model.visiual.FormDataModel;
import com.bringspring.common.model.visiual.TableModel;
import com.bringspring.common.model.visiual.fields.FieLdsModel;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.system.base.service.DblinkService;
import com.bringspring.visualdev.base.entity.VisualdevEntity;
import com.bringspring.visualdev.base.mapper.VisualdevMapper;
import com.bringspring.visualdev.base.model.VisualWebTypeEnum;
import com.bringspring.visualdev.base.service.VisualdevService;
import com.bringspring.visualdev.base.util.VisualUtils;
import com.bringspring.visualdev.generater.factory.CodeGenerateFactory;
import com.bringspring.visualdev.generater.service.VisualdevGenService;
import com.bringspring.visualdev.generater.util.app.AppGenModel;
import com.bringspring.visualdev.generater.util.app.AppGenUtil;
import com.bringspring.visualdev.generater.util.common.CodeGenerateUtil;
import com.bringspring.visualdev.generater.util.custom.VelocityEnum;
import com.bringspring.visualdev.generater.util.workFlow.WorkGenModel;
import com.bringspring.visualdev.generater.util.workFlow.WorkGenUtil;
import lombok.Cleanup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.util.*;


/**
 *
 * @version V1.0.0
 * @copyright 股份有限公司
 * @author 开发平台组
 * @date 2021/3/16
 */
@Service
public class VisualdevGenServiceImpl extends ServiceImpl<VisualdevMapper, VisualdevEntity> implements VisualdevGenService {

    @Autowired
    private UserProvider userProvider;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private DataSourceModel dataSourceModel;
    @Autowired
    private VisualdevService visualdevService;
    @Autowired
    private DblinkService dblinkService;
    @Autowired
    private CodeGenerateFactory CodeGenerateFactory;

    @Override
    public String codeGengerate(String id, DownloadCodeForm downloadCodeForm) throws Exception {
        UserInfo userInfo = userProvider.get();
        VisualdevEntity entity = visualdevService.getInfo(id);
        DbLinkEntity linkEntity = null;
        if (entity != null) {
            // 是否存在关联数据库
            if(StringUtils.isNotEmpty(entity.getDbLinkId())){
                linkEntity = dblinkService.getInfo(entity.getDbLinkId());
            }
            // 是否存在关联表
            if (StringUtils.isNotEmpty(entity.getVisualTables())) {
                FormDataModel model = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
                model.setModule(downloadCodeForm.getModule());
                model.setClassName(NamingStrategy.capitalFirst(NamingStrategy.underlineToCamel(downloadCodeForm.getClassName())));
                model.setAreasName(downloadCodeForm.getModule());
                model.setServiceDirectory(configValueUtil.getServiceDirectoryPath());
                List<FieLdsModel> filterFeildList = JsonUtil.getJsonToList(model.getFields(), FieLdsModel.class);
                model.setFields(JSON.toJSONString(filterFeildList));
                String fileName = entity.getFullName() +System.currentTimeMillis();
                //初始化模板
                VelocityEnum.init.initVelocity(configValueUtil.getTemplateCodePath());

                List<TableModel> list = JsonUtil.getJsonToList(entity.getVisualTables(), TableModel.class);
                //获取主表
                String mainTable = list.stream().filter(t->"1".equals(t.getTypeId())).findFirst().orElse(null).getTable();
                @Cleanup Connection conn = VisualUtils.getDataConn(linkEntity);
                //获取主键
                String pKeyName = VisualUtils.getpKey(conn, mainTable).toLowerCase().trim().replaceAll("f_", "");

                //获取其他子表的主键
                Map<String, Object> childpKeyMap = new HashMap<>(16);
                for (TableModel tableModel : list) {
                    String childKey = VisualUtils.getpKey(conn,tableModel.getTable());
                    if (childKey.length()>2){
                        if ("f_".equals(childKey.substring(0, 2).toLowerCase())) {
                            childKey = childKey.substring(2);
                        }
                    }
                    childpKeyMap.put(tableModel.getTable(), childKey);
                }
                //判断子表名称
                List<String> childTb = new ArrayList();
                if (!StringUtils.isEmpty(downloadCodeForm.getSubClassName())) {
                    childTb = Arrays.asList(downloadCodeForm.getSubClassName().split(","));
                }

                Set<String> set = new HashSet<>(childTb);
                boolean result = childTb.size() == set.size() ? true : false;
                if (!result) {
                    return MsgCode.EXIST001.get();
                }
                String templatesPath = null ;
                if (entity.getType() == 3) {
                    //工作流生成器
                    downloadCodeForm.setModule("form");
                    String templatePath = "TemplateCode1";
                    WorkGenModel workGenModel = new WorkGenModel();
                    workGenModel.setEntity(entity);
                    workGenModel.setPKeyName(pKeyName);
                    workGenModel.setServiceDirectory(configValueUtil.getServiceDirectoryPath());
                    workGenModel.setTemplateCodePath(configValueUtil.getTemplateCodePath());
                    workGenModel.setDownloadCodeForm(downloadCodeForm);
                    workGenModel.setUserInfo(userInfo);
                    workGenModel.setTemplatePath(templatePath);
                    workGenModel.setFileName(fileName);
                    workGenModel.setLinkEntity(linkEntity);
                    workGenModel.setDataSourceModel(dataSourceModel);
                    workGenModel.setModel(model);
                    WorkGenUtil workGenUtil = new WorkGenUtil();
                    workGenUtil.generate(workGenModel);
                    workGenUtil.htmlTemplates(workGenModel);
                }
                if (entity.getType() == 4 ) {

                    if (ObjectUtil.isEmpty(entity.getWebType()) || entity.getWebType().equals(VisualWebTypeEnum.FORM_LIST.getType())){
                        templatesPath="TemplateCode2";
                    }
                    if (ObjectUtil.isNotEmpty(entity.getWebType())&& entity.getWebType().equals(VisualWebTypeEnum.FLOW_FROM.getType() )){
                        //功能流程
                        templatesPath = "TemplateCode3";
                    }
                    if(ObjectUtil.isNotEmpty(entity.getWebType())&& entity.getWebType().equals(VisualWebTypeEnum.FORM.getType())){
                        //纯表单
                        templatesPath = "TemplateCode4";
                    }

                    CodeGenerateUtil generator = CodeGenerateFactory.getGenerator(templatesPath);
                    generator.htmlTemplates(fileName, entity, downloadCodeForm, model, templatesPath, userInfo, configValueUtil, pKeyName);
                    generator.generate(entity, dataSourceModel, fileName, templatesPath, downloadCodeForm, userInfo, configValueUtil,linkEntity);
                    entity.setColumnData(entity.getAppColumnData());
                    AppGenModel appGenModel = new AppGenModel();
                    appGenModel.setEntity(entity);
                    appGenModel.setPKeyName(pKeyName);
                    appGenModel.setServiceDirectory(configValueUtil.getServiceDirectoryPath());
                    appGenModel.setTemplateCodePath(configValueUtil.getTemplateCodePath());
                    appGenModel.setDownloadCodeForm(downloadCodeForm);
                    appGenModel.setUserInfo(userInfo);
                    appGenModel.setTemplatePath(templatesPath);
                    appGenModel.setFileName(fileName);
                    appGenModel.setLinkEntity(linkEntity);
                    appGenModel.setDataSourceModel(dataSourceModel);
                    appGenModel.setModel(model);
                    AppGenUtil appGenUtil = new AppGenUtil();
                    appGenUtil.htmlTemplates(appGenModel);
                }
                return fileName;
            }
        }
        return null;
    }

}
